import os
import subprocess
from utils import split_text_by_length

def convert_file_to_mp3(fname, file_text, voice, ui, rate=1.0):
    import edge_tts
    import asyncio
    import socket
    # 联网判断
    try:
        socket.create_connection(("www.baidu.com", 80), timeout=3)
    except Exception:
        ui.show_error("未检测到网络，无法进行TTS转换")
        ui.file_conversion_status[fname] = 'error: 无网络'
        return
    segments = split_text_by_length(file_text, 300)
    generated_mp3s = []
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    converted_chars = 0
    # 语速转换为edge-tts的rate参数（百分比字符串）
    rate_percent = int((rate - 1.0) * 100)
    if rate_percent == 0:
        rate_str = "+0%"
    elif rate_percent > 0:
        rate_str = f"+{rate_percent}%"
    else:
        rate_str = f"{rate_percent}%"
    for idx, seg in enumerate(segments):
        temp_mp3 = f"{fname}_seg{idx}.mp3"
        loop.run_until_complete(
            edge_tts.Communicate(text=seg, voice=voice, rate=rate_str).save(temp_mp3)
        )
        generated_mp3s.append(temp_mp3)
        converted_chars += len(seg)
        ui.converted_chars = converted_chars
        ui.update_progress(ui.converted_chars, ui.total_chars)
    # 合并mp3
    try:
        concat_file = f"{fname}_concat.txt"
        with open(concat_file, "w", encoding="utf-8") as f:
            for mp3 in generated_mp3s:
                f.write(f"file '{mp3}'\n")
        out_mp3 = os.path.splitext(fname)[0] + ".mp3"
        cmd = [
            "ffmpeg", "-y", "-f", "concat", "-safe", "0",
            "-i", concat_file, "-c", "copy", out_mp3
        ]
        subprocess.run(cmd, check=True)
        ui.file_conversion_status[fname] = 'done'
        ui.file_segments_info[fname] = []
        # 删除中间文件
        for mp3 in generated_mp3s:
            try:
                os.remove(mp3)
            except Exception:
                pass
        try:
            os.remove(concat_file)
        except Exception:
            pass
    except Exception as e:
        ui.file_conversion_status[fname] = f'error: {e}'